import { urlToObject } from '../uitls'
import RouterPackage from '../package.json'

const methodsToPatch  = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab']
const uniProto = {
	navigateTo: uni.navigateTo,
	redirectTo: uni.redirectTo,
	reLaunch: uni.reLaunch,
	switchTab: uni.switchTab
}

const routeGuard = {
	version: RouterPackage.version,
	install (app){
		methodsToPatch.forEach(method=>{
			const original = uniProto[method]
			uni[method] = (option)=>{
				return new Promise((reslove, reject)=>{
					this.reject = reject
					let { success, fail, complete } = option
					option.success = (res)=>{
						success?.(res)
						reslove(res)
						// 触发后置钩子
						this.afterEachCallback(this.to, this.from, this.method)
					}
					option.fail = (err)=>{
						fail?.(err)
						reject(err)
					}
					option.complete = (res)=>{
						complete?.(res)
						this.isReject = true
					}
					
					this.option = option
					this.method = method
					const routeList = getCurrentPages()
					this.to = urlToObject(option.url)
					this.from = routeList[routeList.length - 1] || {}
					this.beforeEachCallback(this.to, this.from, this.next.bind(this), this.method)
					// 执行回调完成后判断路由是否被拦截,并执行回调
					this.promisePending()
				})
			}
		})
	},
	// reject 失败回调
	reject:()=>{},
	isReject: true,
	promisePending(){
		if(this.isReject){
			this.reject({
				errMsg: 'navigateTo:fail page `/pages/test/index1` is blocked',
				blocked: true
			})
		}
	},
	to: {},
	from: {},
	/**
	 * 执行进行此次跳转
	 */
	next(){
		this.isReject = false
		uniProto[this.method](this.option)
	},
	option: {},
	method:'',
	/**
	 * @param { function } callback 回调函数
	 */
	beforeEach(callback=this.beforeEachCallback){
		this.beforeEachCallback = callback
	},
	/**
	 * 路由跳转前置回调
	 * @param { object } to 我们要导航到的路由地址
	 * @param { object } from 我们从哪里来的路由地址
	 * @param { function } next 回调以验证导航
	 * @param { string } type 跳转方式
	 */
	beforeEachCallback(to, from, next, type){
		return next()
	},
	/**
	 * @param { function } callback 回调函数
	 */
	afterEach(callback=this.afterEachCallback){
		this.afterEachCallback = callback
	},
	/**
	 * 路由跳转后置回调
	 * @param { object } to 我们要导航到的路由地址
	 * @param { object } from 我们从哪里来的路由地址
	 * @param { string } type 跳转方式
	 */
	afterEachCallback(to, from, type){},
	
}

export default routeGuard